package pers.karl.security.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.DefaultLoginPageConfigurer;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import pers.karl.security.utils.ResponseUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

@EnableWebSecurity(debug = true)
public class WebSecurityConfig {

    @Configuration
    public static class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {

            // CSRF相关
//            http.csrf().csrfTokenRepository();
            http.csrf().disable();

            // 除以下指定的部分，其它都需要认证
            http.authorizeRequests()
                    .antMatchers("/csrf").permitAll()
                    .mvcMatchers("/","/index.html","/html/**","/js/**","/css/**").permitAll()
                    .anyRequest().authenticated();

            // 开放form登录
            http.formLogin()
                    // 登录成功处理
                    .successHandler(new LoginSuccessHandler())
                    // 登录失败处理
                    .failureHandler((httpServletRequest, response, exception) ->
                            ResponseUtils.writeJson(response, HttpStatus.UNAUTHORIZED, exception.getMessage()));

            // 定时化访问拒绝的处理方式
            http.exceptionHandling()
                    // 尚未认证时的拒绝策略
                    .authenticationEntryPoint((request, response, authException) ->
                        ResponseUtils.writeJson(response, HttpStatus.UNAUTHORIZED, "尚未登录")
                    )
                    .accessDeniedHandler((request, response, accessDeniedException) -> {
                        if (!response.isCommitted()) {
                            ResponseUtils.writeJson(response,HttpStatus.FORBIDDEN, accessDeniedException.getMessage());
                        }
                    });

        }
    }

}